#include "StdAfx.h"
#include "TabLogic.h"
#include "TabDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

TabLogic::TabLogic(TabDlg* tabDlg)
	: mTabDlg(tabDlg)
{
	
}

TabLogic::~TabLogic(void)
{
}

bool TabLogic::Initialize()
{
	InputHook::Initialize(this);
	//InputHook::Instance()->SetStartMouse(this);
	if (!InputHook::Instance()->Start())
	{
		return false;
	}
	InitInputKeyToChar();
	return true;
}

void TabLogic::Release()
{
	InputHook::Instance()->Stop();
	InputHook::Release();

}

bool TabLogic::OnKey( WPARAM wparam, const KBDLLHOOKSTRUCT& event )
{
	if (wparam == WM_SYSKEYDOWN && IsAltPress() )
	{
		if (event.vkCode == VK_TAB)
		{
			OnAltTabStart();
			return true;
		}
		if (mTabDlg->IsWindowShow())
		{
			if (event.vkCode == VK_UP)
			{
				mTabDlg->LastSelect();	
				return true;
			}
			else if (event.vkCode == VK_DOWN)
			{
				mTabDlg->NextSelect();
				return true;
			}
			else if (event.vkCode == VK_RETURN)
			{
				mTabDlg->ConfirmSelect();
				return true;
			}
			else if (DWORD charKey = GetKeyChar(event.vkCode))
			{
				OnInputKey(charKey);
				return true;
			}
		}
		
		
		return false;
	}
	if (wparam == WM_KEYUP && (event.vkCode == VK_LMENU || event.vkCode == VK_RMENU))
	{
		OnAltUp();
		return false;
	}

	//LogDebug(FMTVAR(event.vkCode) + FMTVAR(event.scanCode) + FMTVAR(wparam));
	return false;
}

bool TabLogic::OnMouse( WPARAM wparam, const MSLLHOOKSTRUCT& event )
{
	//LogDebug(FMTVAR(wparam) +  FMTVAR(IsAltPress()) + FMTVAR(WM_MOUSEHWHEEL));
	if (wparam == WM_MOUSEWHEEL  && IsAltPress() )
	{
		if (mTabDlg->IsWindowShow())
		{
			short delta = (short)HIWORD(event.mouseData);
			if (delta > 0)
			{
				mTabDlg->LastSelect();	
			}
			else
			{
				mTabDlg->NextSelect();
			}
		}


		return false;
	}
	return false;
}

void TabLogic::OnAltTabStart()
{
	IsShiftPress() ? mTabDlg->LastSelect() : mTabDlg->NextSelect();
	LogFuncName();
}

void TabLogic::OnAltUp()
{
	LogFuncName();
	mTabDlg->ConfirmSelect();
}

bool TabLogic::IsShiftPress()
{
	return HIWORD(GetKeyState(VK_LSHIFT)) ||  HIWORD(GetKeyState(VK_RSHIFT)) ? true : false;
}

bool TabLogic::IsAltPress()
{
	return HIWORD(GetKeyState(VK_LMENU)) ? true : false;
}

bool TabLogic::OnInputKey(DWORD charKey)
{
	mTabDlg->InputKey(charKey);
	return false;
}

bool TabLogic::IsCapitalActive()
{
	return LOWORD(GetKeyState(VK_CAPITAL)) & 0x1 ? true : false;
}

void TabLogic::MakeCommonMap( DWORD orgKey, DWORD shiftKey )
{
	CharData d = {orgKey, shiftKey ? shiftKey : orgKey};
	mInputKeyToChar.insert(std::make_pair(orgKey, d));
}

void TabLogic::MakeSpecialMap( DWORD vkKey, DWORD orgKey, DWORD shiftKey )
{
	CharData d = {orgKey, shiftKey};
	mInputKeyToChar.insert(std::make_pair(vkKey, d));
}

void TabLogic::InitInputKeyToChar()
{
	MakeCommonMap('A', 'a');
	MakeCommonMap('B', 'b');
	MakeCommonMap('C', 'c');
	MakeCommonMap('D', 'd');
	MakeCommonMap('E', 'e');
	MakeCommonMap('F', 'f');
	MakeCommonMap('G', 'g');
	MakeCommonMap('H', 'h');
	MakeCommonMap('I', 'i');
	MakeCommonMap('J', 'j');
	MakeCommonMap('K', 'k');
	MakeCommonMap('L', 'l');
	MakeCommonMap('M', 'm');
	MakeCommonMap('N', 'n');
	MakeCommonMap('O', 'o');
	MakeCommonMap('P', 'p');
	MakeCommonMap('Q', 'q');
	MakeCommonMap('R', 'r');
	MakeCommonMap('S', 's');
	MakeCommonMap('T', 't');
	MakeCommonMap('U', 'u');
	MakeCommonMap('V', 'v');
	MakeCommonMap('W', 'w');
	MakeCommonMap('X', 'x');
	MakeCommonMap('Y', 'y');
	MakeCommonMap('Z', 'z');

	MakeCommonMap('1', '!');
	MakeCommonMap('2', '@');
	MakeCommonMap('3', '#');
	MakeCommonMap('4', '$');
	MakeCommonMap('5', '%');
	MakeCommonMap('6', '^');
	MakeCommonMap('7', '&');
	MakeCommonMap('8', '*');
	MakeCommonMap('9', '(');
	MakeCommonMap('0', ')');

	MakeSpecialMap(VK_OEM_3, '`', '~');

	MakeSpecialMap(VK_OEM_MINUS, '_', '-');
	MakeSpecialMap(VK_OEM_PLUS, '=', '+');
	MakeSpecialMap(VK_OEM_4, '[', '{');
	MakeSpecialMap(VK_OEM_6, ']', '}');
	MakeSpecialMap(VK_OEM_1, ';', ':');
	MakeSpecialMap(VK_OEM_5, '\'', '\"');
	MakeSpecialMap(VK_OEM_COMMA, ',', '<');
	MakeSpecialMap(VK_OEM_PERIOD, '.', '>');
	MakeSpecialMap(VK_OEM_2, '/', '?');
	MakeSpecialMap(VK_OEM_5, '\\', '|');

	MakeCommonMap(VK_BACK);
	MakeCommonMap(VK_SPACE);
	MakeCommonMap(VK_PRIOR);
	MakeCommonMap(VK_NEXT);
	MakeCommonMap(VK_END);
	MakeCommonMap(VK_HOME);
	MakeCommonMap(VK_LEFT);
	MakeCommonMap(VK_RIGHT);
	MakeCommonMap(VK_DELETE);
// 	MakeMap(
// 	{"VK_SHIFT",          0x10},
// 	{"VK_CTRL",        0x11},
// 	{"VK_MENU",           0x12},
// 	{"VK_BACK",           0x08},
// 	{"VK_TAB",            0x09},
// 	{"VK_SPACE",         0x20},
// 	{"VK_PRIOR",         0x21},
// 	{"VK_NEXT",           0x22},
// 	{"VK_END",            0x23},
// 	{"VK_HOME",           0x24},
// 	{"VK_LEFT",           0x25},
// 	{"VK_UP   ",          0x26},
// 	{"VK_RIGHT ",        0x27},
// 	{"VK_DOWN  ",      0x28},
// 	{"VK_SELECT",         0x29},
// 	{"VK_PRINT ",         0x2A},
// 	{"VK_EXE",        0x2B},
// 	{"VK_SNAPSHOT",       0x2C},
// 	{"VK_INS   ",      0x2D},
// 	{"VK_DEL   ",      0x2E},
// 	{"VK_NUM0 ",       0x60},
// 	{"VK_NUM1  ",      0x61},
// 	{"VK_NUM2   ",     0x62},
// 	{"VK_NUM3  ",      0x63},
// 	{"VK_NUM4  ",      0x64},
// 	{"VK_NUM5  ",      0x65},
// 	{"VK_NUM6  ",      0x66},
// 	{"VK_NUM7  ",      0x67},
// 	{"VK_NUM8  ",      0x68},
// 	{"VK_NUM9  ",      0x69},
// 	{"VK_*",      0x6A},
// 	{"VK_+",      0x6B},
// 	{"VK_SEPARATOR ",     0x6C},
// 	{"VK_-",      0x6D},
// 	{"VK_DEL",      0x6E},
// 	{"VK_/",        0x6F},
// 	{"VK_F1   ",          0x70},
// 	{"VK_F2  ",           0x71},
// 	{"VK_F3  ",           0x72},
// 	{"VK_F4  ",           0x73},
// 	{"VK_F5  ",           0x74},
// 	{"VK_F6  ",           0x75},
// 	{"VK_F7  ",           0x76},
// 	{"VK_F8  ",           0x77},
// 	{"VK_F9   ",          0x78},
// 	{"VK_F10 ",           0x79},
// 	{"VK_F11 ",           0x7A},
// 	{"VK_F12 ",           0x7B},
// 	{";",          0xBA },
// 	{"=",       0xBB}, 
// 	{",",      0xBC},  
// 	{"-",      0xBD},  
// 	{".",     0xBE},  
// 	{"/",         0xBF}, 
// 	{"`",          0xC0}, 

}

DWORD TabLogic::GetKeyChar( DWORD key )
{
	LogDebug(FMTVAR(key));
	InputKeyToChar::iterator it = mInputKeyToChar.find(key);
	if (it == mInputKeyToChar.end())
	{
		return 0;
	}

	if (IsAlpha(key))
	{
		return IsCapitalActive() == IsShiftPress() ? it->second.shiftKey : it->second.orgKey;
	}
	else
	{
		return IsShiftPress() ? it->second.shiftKey : it->second.orgKey;
	}
	return 0;
}

bool TabLogic::IsAlpha( DWORD key )
{
	return key >= 'A' && key <= 'Z';
}

bool TabLogic::OnMsg( WPARAM wparam, LPARAM lParam )
{
	TCHAR tmp[1024];
	::GetWindowText((HWND)lParam, tmp, 1024);
	OutputDebugString(tmp);
	OutputDebugString(_T("\n"));
	//LogDebug(FMTVAR(wparam) + FMTVAR(lParam));
	return true;
}
